package com.sinoatma.physignsmonitor.utils

import android.os.AsyncTask
import android.util.Log
import com.jeremyliao.liveeventbus.LiveEventBus
import com.sinoatma.physignsmonitor.MyApp.Companion.stopMonitorFlag1
import com.sinoatma.physignsmonitor.MyApp.Companion.stopMonitorFlag2
import com.sinoatma.physignsmonitor.bean.ExcelColumnHead
import com.sinoatma.physignsmonitor.bean.MonitorRecordsBean
import org.apache.poi.openxml4j.exceptions.InvalidFormatException
import org.apache.poi.ss.usermodel.*
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException

// 假设这是一个用于处理Excel相关操作的服务实现类，实现了某些Excel相关的业务逻辑
class ExcelServiceImpl {

    /**
     * 导出采血生命体征数据，将生命体征数据列表写入到Excel文件中
     * @param dataList 生命体征数据集合，每个元素代表一行数据对应的实体类对象
     * @param headerList 列头信息集合，用于定义Excel文件中每列的标题及宽度等信息
     * @param filePath 文件路径，指定要生成或写入的Excel文件的位置
     * @return 布尔值，表示写入操作是否成功，目前固定返回true，若有错误可根据实际情况调整返回值
     */
    fun bloodCollectExportExcel1(dataList: List<MonitorRecordsBean>, headerList: List<ExcelColumnHead>, filePath: String): Boolean {
        val file = File(filePath)
        try {
            val workbook = if (file.exists()) getExistingWorkbook(file) else XSSFWorkbook()
            val sheet = if (workbook.numberOfSheets == 0) {
                val newSheet = workbook.createSheet("Sheet1")
                createHeaderRow(workbook, newSheet, headerList)
                newSheet
            } else {
                val existingSheet = workbook.getSheetAt(0)
                if (existingSheet.lastRowNum == -1) {
                    createHeaderRow(workbook, existingSheet, headerList)
                }
                existingSheet
            }
            var rowNum = sheet.lastRowNum + 1
            val iterator = dataList.iterator()
            while (iterator.hasNext()) {
                val data = iterator.next()
                val row = sheet.createRow(rowNum++)
                row.heightInPoints = 22f
                setRowData(row, data)
                // 如果需要删除元素，可以使用 iterator.remove()
            }

            // 整体设置样式
            setOverallCellStyle(workbook, sheet, headerList.size)

            // 使用异步任务来执行文件写入操作，避免阻塞主线程
            WriteExcelTask1(workbook, file).execute()
        } catch (e: IOException) {
            e.printStackTrace()
        } catch (e: InvalidFormatException) {
            e.printStackTrace()
        }
        return true
    }


    fun bloodCollectExportExcel2(dataList: List<MonitorRecordsBean>, headerList: List<ExcelColumnHead>, filePath: String): Boolean {
        val file = File(filePath)
        try {
            val workbook = if (file.exists()) getExistingWorkbook(file) else XSSFWorkbook()
            val sheet = if (workbook.numberOfSheets == 0) {
                val newSheet = workbook.createSheet("Sheet1")
                createHeaderRow(workbook, newSheet, headerList)
                newSheet
            } else {
                val existingSheet = workbook.getSheetAt(0)
                if (existingSheet.lastRowNum == -1) {
                    createHeaderRow(workbook, existingSheet, headerList)
                }
                existingSheet
            }

            var rowNum = sheet.lastRowNum + 1
//            for (data in dataList) {
//                val row = sheet.createRow(rowNum++)
//                row.heightInPoints = 22f
//                setRowData(row, data)
//            }
            val iterator = dataList.iterator()
            while (iterator.hasNext()) {
                val data = iterator.next()
                val row = sheet.createRow(rowNum++)
                row.heightInPoints = 22f
                setRowData(row, data)
                // 如果需要删除元素，可以使用 iterator.remove()
            }

            // 整体设置样式
            setOverallCellStyle(workbook, sheet, headerList.size)

            // 使用异步任务来执行文件写入操作，避免阻塞主线程
            WriteExcelTask2(workbook, file).execute()
        } catch (e: IOException) {
            e.printStackTrace()
        } catch (e: InvalidFormatException) {
            e.printStackTrace()
        }
        return true
    }




    /**
     * 获取已存在的工作簿对象，如果文件不存在会抛出异常，需要在调用处处理
     * @param file 表示要读取的Excel文件对象
     * @return 返回从文件中读取并创建的Workbook对象，可用于后续对Excel文件的操作
     */
    private fun getExistingWorkbook(file: File): Workbook {
        if (file.length() == 0L) {
            // 这里可以根据具体情况抛出更合适的异常，或者返回一个空的工作簿对象（如果合适的话）
            throw IllegalArgumentException("文件为空，无法读取")
        }
        FileInputStream(file).use { fis ->
            return WorkbookFactory.create(fis)
        }
    }

    /**
     * 创建标题行，设置标题行的样式、字体、列宽以及写入列标题内容
     * @param workbook 整个Excel文件对应的工作簿对象，用于创建样式、字体等相关资源
     * @param sheet 当前操作的工作表对象，用于创建标题行以及设置列宽等操作
     * @param headerList 列头信息集合，包含每列的标题名称和宽度等信息
     */
    private fun createHeaderRow(workbook: Workbook, sheet: Sheet, headerList: List<ExcelColumnHead>) {
        val headerRow = sheet.createRow(0)
        headerRow.heightInPoints = 25f

        // 设置标题行背景色，创建并配置标题行的单元格样式
        val headerCellStyle = workbook.createCellStyle()
        headerCellStyle.alignment = HorizontalAlignment.CENTER
        headerCellStyle.verticalAlignment = VerticalAlignment.CENTER
        headerCellStyle.fillForegroundColor = IndexedColors.GREY_25_PERCENT.index
        headerCellStyle.fillPattern = FillPatternType.SOLID_FOREGROUND

        val headerFont = workbook.createFont()
        headerFont.fontName = "微软雅黑"
        headerFont.fontHeightInPoints = 13
        headerCellStyle.setFont(headerFont)

        var cellNum = 0
        for (columnInfoModel in headerList) {
            val cell = headerRow.createCell(cellNum++)
            cell.setCellValue(columnInfoModel.name)
            cell.cellStyle = headerCellStyle
            sheet.setColumnWidth(cellNum - 1, columnInfoModel.columnWidth)
        }
    }

    /**
     * 将给定的数据对象的各个字段值设置到对应的Excel行的单元格中
     * @param row 要设置数据的Excel行对象
     * @param data 包含具体数据的实体类对象，其字段值将被提取并设置到行的单元格中
     */
    private fun setRowData(row: Row, data: MonitorRecordsBean) {
//        val fields = data.javaClass.declaredFields
        val cells = listOf(
            data.bloodDonationCode,
            data.name,
            data.sex,
            data.age,
            data.bloodOxygen,
            data.bloodPressure,
            data.pulse,
            data.temperature,
            data.monitorTime,
            data.earlyWarningTime,
            data.reasonsEarlyWarning,
            data.dataAcquisitionDeviceNumber
        )
//        var cellNum = 0
        for (i in cells.indices) {
            val cell = row.createCell(i)
            cell.setCellValue(cells[i])
       /*     try {
                field.isAccessible = true
                val value = field[data]
                val cell = row.createCell(cellNum++)
                cell.setCellValue(value as String)
            } catch (e: IllegalAccessException) {
                e.printStackTrace()
            }*/
        }
    }

    /**
     * 整体设置工作表中数据行的单元格样式，包括字体、对齐方式等
     * @param workbook 整个Excel文件对应的工作簿对象，用于创建通用的单元格样式所依赖的字体等资源
     * @param sheet 当前操作的工作表对象，用于遍历行和列来设置每个单元格的样式
     * @param columnCount 列的数量，用于控制循环设置样式的列范围
     */
    private fun setOverallCellStyle(workbook: Workbook, sheet: Sheet, columnCount: Int) {
        // 创建通用样式，设置字体、对齐方式等属性
        val commonCellStyle = workbook.createCellStyle()
        commonCellStyle.alignment = HorizontalAlignment.CENTER
        commonCellStyle.verticalAlignment = VerticalAlignment.CENTER
        val font = workbook.createFont()
        font.fontName = "微软雅黑"
        font.fontHeightInPoints = 12
        commonCellStyle.setFont(font)

        // 遍历数据行，为每一行的每个单元格设置通用样式
        for (i in 1..sheet.lastRowNum) {
            val row = sheet.getRow(i)?: continue
            for (j in 0 until columnCount) {
                val cell = row.getCell(j)
                if (cell!= null) {
                    cell.cellStyle = commonCellStyle
                }
            }
        }
    }

    /**
     * 自定义的异步任务类，用于在后台线程执行将工作簿内容写入到文件的操作
     */
    inner class WriteExcelTask1(private val workbook: Workbook, private val file: File) : AsyncTask<Void, Void, Void>() {

        override fun doInBackground(vararg params: Void?): Void? {
            try {
                FileOutputStream(file).use { fos ->
                    workbook.write(fos)
                }
                if (stopMonitorFlag1==1){
                    LiveEventBus.get("upFile",Int::class.java).post(1)
                }
            } catch (e: IOException) {
                e.printStackTrace()
                LiveEventBus.get("upFile",Int::class.java).post(3)
            }
            return null
        }
    }


    /**
     * 自定义的异步任务类，用于在后台线程执行将工作簿内容写入到文件的操作
     */
    inner class WriteExcelTask2(private val workbook: Workbook, private val file: File) : AsyncTask<Void, Void, Void>() {

        override fun doInBackground(vararg params: Void?): Void? {
            try {
                FileOutputStream(file).use { fos ->
                    workbook.write(fos)
                }
                if (stopMonitorFlag2==1){
                    LiveEventBus.get("upFile",Int::class.java).post(2)
                }
            } catch (e: IOException) {
                e.printStackTrace()
                LiveEventBus.get("upFile",Int::class.java).post(3)
            }
            return null
        }
    }

}

